/**
 * 位置工具类
 * 提供定位、城市解析和位置信息管理功能
 */

class LocationManager {
    constructor() {
        this.isLocating = false; // 防止重复定位
        this.locationCache = null; // 位置缓存
        this.locationPromise = null; // 定位Promise缓存
    }

    /**
     * 获取缓存的位置信息
     */
    getCachedLocation() {
        const cached = uni.getStorageSync('userLocation');
        if (cached && Date.now() - cached.timestamp < 30 * 60 * 1000) { // 30分钟内的缓存有效
            console.log('📍 使用缓存的位置信息');
            return cached.location;
        }
        return null;
    }

    /**
     * 保存位置信息到缓存
     */
    saveLocationToCache(location) {
        uni.setStorageSync('userLocation', {
            location,
            timestamp: Date.now()
        });
        this.locationCache = location;
        
        // 同时缓存城市信息（如果有）
        if (location.cityInfo) {
            uni.setStorageSync('cityInfo', {
                location: { latitude: location.latitude, longitude: location.longitude },
                cityInfo: location.cityInfo,
                timestamp: Date.now()
            });
        }
        
        console.log('💾 位置信息已缓存');
    }

    /**
     * 清除位置缓存
     */
    clearLocationCache() {
        uni.removeStorageSync('userLocation');
        this.locationCache = null;
        console.log('🗑️ 位置缓存已清除');
    }

    /**
     * 获取用户定位
     * @param {Boolean} forceRefresh 是否强制刷新定位，不使用缓存
     */
    async getUserLocation(forceRefresh = false) {
        // 如果正在定位，返回同一个Promise
        if (this.isLocating && !forceRefresh) {
            return this.locationPromise;
        }

        // 检查缓存
        if (!forceRefresh) {
            const cachedLocation = this.getCachedLocation();
            if (cachedLocation) {
                return cachedLocation;
            }
        }

        this.isLocating = true;

        // 创建定位Promise
        this.locationPromise = new Promise((resolve, reject) => {
            console.log('📍 开始获取用户定位...');
            
            // 检查是否已经授权定位
            uni.getSetting({
                success: (settingRes) => {
                    // 如果没有授权，请求授权
                    if (!settingRes.authSetting['scope.userLocation']) {
                        console.log('🔍 未授权定位，请求授权...');
                        
                        // 显示授权提示
                        uni.showModal({
                            title: '位置授权',
                            content: '为了给您推荐附近的机构，我们需要获取您的位置信息',
                            success: (modalRes) => {
                                if (modalRes.confirm) {
                                    // 用户同意后，再次请求授权
                                    uni.authorize({
                                        scope: 'scope.userLocation',
                                        success: () => {
                                            console.log('✅ 用户已授权定位权限');
                                            this.getLocation(resolve, reject);
                                        },
                                        fail: (authError) => {
                                            console.error('❌ 授权定位失败:', authError);
                                            // 引导用户手动打开授权
                                            this.openLocationSettings(reject);
                                        }
                                    });
                                } else {
                                    console.log('❌ 用户拒绝授权定位');
                                    reject(new Error('用户拒绝授权定位'));
                                }
                            }
                        });
                    } else {
                        // 已经授权，直接获取定位
                        this.getLocation(resolve, reject);
                    }
                },
                fail: (settingError) => {
                    console.error('❌ 获取设置失败:', settingError);
                    reject(new Error('获取设置失败'));
                }
            });
        }).finally(() => {
            this.isLocating = false;
        });

        return this.locationPromise;
    }

    /**
     * 实际获取定位的方法
     */
    getLocation(resolve, reject) {
        uni.getLocation({
            type: 'gcj02',
            altitude: true,
            success: async (res) => {
                const location = {
                    latitude: res.latitude,
                    longitude: res.longitude,
                    accuracy: res.accuracy,
                    altitude: res.altitude || 0
                };
                
                console.log('✅ 定位成功，坐标:', location);
                
                // 解析城市信息
                try {
                    // 检查是否可以调用API，如果API已达到上限，则直接使用默认城市信息
                    if (this.isAPIQuotaExceeded()) {
                        console.log('⚠️ API已达上限，使用默认城市信息');
                        location.cityInfo = this.getDefaultCityInfo();
                    } else {
                        const cityInfo = await this.getCityInfo(location.latitude, location.longitude);
                        location.cityInfo = cityInfo;
                    }
                    
                    // 保存到缓存
                    this.saveLocationToCache(location);
                    resolve(location);
                } catch (error) {
                    console.error('❌ 解析城市信息失败:', error.message);
                    // 即使解析城市失败，也返回坐标信息
                    // 在失败情况下，使用默认城市信息作为备用
                    location.cityInfo = this.getDefaultCityInfo();
                    this.saveLocationToCache(location);
                    resolve(location);
                }
            },
            fail: (err) => {
                console.error('❌ 获取定位失败:', err.errMsg || err);
                reject(new Error(`获取定位失败: ${err.errMsg || err}`));
            }
        });
    }

    /**
     * 解析经纬度对应的城市信息
     * 使用腾讯地图API进行逆地址解析
     */
    async getCityInfo(latitude, longitude) {
        console.log('🏙️ 开始解析城市信息...');
        
        // 检查是否有缓存的城市信息且在有效期内
        const cachedCityInfo = this.getCachedCityInfo();
        if (cachedCityInfo && this.isSameLocation(cachedCityInfo.location, {latitude, longitude})) {
            console.log('📍 使用缓存的城市信息');
            return cachedCityInfo.cityInfo;
        }
        
        // 检查API是否已达到调用上限，如果已超限则直接返回备用数据
        if (this.isAPIQuotaExceeded()) {
            console.log('⚠️ 地图API调用量已达上限，直接使用备用数据');
            return this.getDefaultCityInfo();
        }
        
        // 从manifest.json配置中获取腾讯地图API密钥
        const mapKey = 'WK3BZ-Y3EK3-WYP3I-RHADJ-5EXZ3-QOBGK';
        
        try {
            // 调用腾讯地图API进行逆地址解析
            return await this.callMapAPI(mapKey, latitude, longitude);
        } catch (error) {
            console.error('❌ 城市信息解析异常:', error);
            
            // 如果API调用失败，返回模拟数据作为备用方案
            return this.getDefaultCityInfo();
        }
    }
      
      /**
       * 获取默认的城市信息（备用数据）
       */
      getDefaultCityInfo() {
          return {
              province: '北京市',
              city: '北京市',
              district: '朝阳区',
              address: '北京市朝阳区CBD商务中心',
              formattedAddress: '北京市朝阳区CBD商务中心'
          };
      }
      
      /**
     * 调用地图API的封装方法
     */
    async callMapAPI(mapKey, latitude, longitude) {
        // 检查是否可以调用API
        if (!this.canCallMapAPI()) {
            const message = '⏱️ 地图API调用频率限制或已达到调用上限，使用备用数据';
            console.log(message);
            throw new Error(message);
        }
        
        try {
            console.log(`🌐 发起地图API请求，坐标: ${latitude},${longitude}`);
            return await new Promise((resolve, reject) => {
                uni.request({
                    url: 'https://apis.map.qq.com/ws/geocoder/v1/',
                    data: {
                        location: `${latitude},${longitude}`,
                        key: mapKey,
                        get_poi: 0
                    },
                    timeout: 10000, // 设置10秒超时
                    success: (res) => {
                        console.log('📡 地图API响应状态:', res.statusCode);
                        
                        if (res.statusCode === 200) {
                            if (res.data.status === 0) {
                                const result = res.data.result;
                                console.log('✅ 城市信息解析成功:', result);
                                
                                // 保存城市信息缓存
                                const cityInfo = {
                                    province: result.address_component.province || '北京市',
                                    city: result.address_component.city || '北京市',
                                    district: result.address_component.district || '朝阳区',
                                    address: result.address,
                                    formattedAddress: result.formatted_addresses?.recommend || result.address
                                };
                                
                                // 记录API调用时间
                                this.saveMapAPICallTime();
                                
                                resolve(cityInfo);
                            } else {
                                console.error('❌ 地图API错误:', res.data.message);
                                // 对于调用量上限的错误，特殊处理
                                if (res.data.message.includes('调用量已达到上限') || res.data.message.includes('超出日配额')) {
                                    this.handleAPIQuotaExceeded();
                                }
                                reject(new Error(`地图API错误: ${res.data.message}`));
                            }
                        } else {
                            console.error('❌ 地图API网络错误，状态码:', res.statusCode);
                            reject(new Error(`地图API网络错误，状态码: ${res.statusCode}`));
                        }
                    },
                    fail: (err) => {
                        console.error('❌ 城市信息解析请求失败:', err.errMsg || err);
                        reject(new Error(`请求失败: ${err.errMsg || err}`));
                    }
                });
            });
        } catch (error) {
            console.error('❌ 地图API调用异常:', error.message);
            throw error;
        }
    }
    
    /**
     * 获取缓存的城市信息
     */
    getCachedCityInfo() {
        const cached = uni.getStorageSync('cityInfo');
        if (cached && Date.now() - cached.timestamp < 60 * 60 * 1000) { // 1小时内的缓存有效
            return cached;
        }
        return null;
    }
    
    /**
     * 检查两个位置是否相同（在一定误差范围内）
     */
    isSameLocation(loc1, loc2, threshold = 0.01) { // 约1公里的误差范围
        if (!loc1 || !loc2) return false;
        const latDiff = Math.abs(loc1.latitude - loc2.latitude);
        const lngDiff = Math.abs(loc1.longitude - loc2.longitude);
        return latDiff < threshold && lngDiff < threshold;
    }
    
    /**
     * 检查是否可以调用地图API（避免频繁调用和调用量超限）
     */
    canCallMapAPI() {
        // 首先检查API是否已达到调用上限
        if (this.isAPIQuotaExceeded()) {
            return false;
        }
        
        // 然后检查调用频率限制
        const lastCallTime = uni.getStorageSync('lastMapAPICallTime') || 0;
        const minInterval = 30 * 1000; // 30秒最小调用间隔
        return Date.now() - lastCallTime > minInterval;
    }
    
    /**
     * 保存地图API调用时间
     */
    saveMapAPICallTime() {
        uni.setStorageSync('lastMapAPICallTime', Date.now());
    }
    
    /**
     * 处理API调用量达到上限的情况
     */
    handleAPIQuotaExceeded() {
        // 记录API达到上限的时间，设置较长的冷却时间 (24小时)
        const cooldownTime = 24 * 60 * 60 * 1000;
        uni.setStorageSync('apiQuotaExceededTime', Date.now() + cooldownTime);
        console.warn('⚠️ 地图API调用量已达上限，将在24小时内使用备用数据');
        
        // 显示提示信息给用户
        uni.showToast({
            title: '地图服务暂时繁忙，将使用本地数据为您服务',
            icon: 'none',
            duration: 3000
        });
    }

    /**
     * 检查API是否已达到调用上限
     */
    isAPIQuotaExceeded() {
        const quotaExceededTime = uni.getStorageSync('apiQuotaExceededTime') || 0;
        return Date.now() < quotaExceededTime;
    }

    /**
     * 打开位置设置页面
     */
    openLocationSettings(reject) {
        uni.showModal({
            title: '需要位置权限',
            content: '请在系统设置中允许应用获取位置信息，以便为您推荐附近的机构',
            confirmText: '去设置',
            cancelText: '取消',
            success: (res) => {
                if (res.confirm) {
                    // 打开设置页面
                    uni.openSetting({
                        success: (settingRes) => {
                            console.log('🔧 设置页面返回:', settingRes.authSetting);
                            if (settingRes.authSetting['scope.userLocation']) {
                                console.log('✅ 用户在设置中授权了定位');
                                // 重新获取定位
                                this.getUserLocation(true).then(resolve => {
                                    reject = null; // 避免重复reject
                                }).catch();
                            }
                        }
                    });
                } else {
                    if (reject) {
                        reject(new Error('用户拒绝授权定位'));
                    }
                }
            }
        });
    }

    /**
     * 检查是否需要定位（是否已获取有效坐标）
     */
    needLocation() {
        const cachedLocation = this.getCachedLocation();
        return !cachedLocation;
    }
}

// 创建单例实例
const locationManager = new LocationManager();

export default locationManager;

// 导出常用方法
export const {
    getUserLocation,
    getCachedLocation,
    saveLocationToCache,
    clearLocationCache,
    needLocation
} = locationManager;